/*
 * Copyright (c) 2018 Zilliqa
 * This source code is being disclosed to you solely for the purpose of your
 * participation in testing Zilliqa. You may view, compile and run the code for
 * that purpose and pursuant to the protocols and algorithms that are programmed
 * into, and intended by, the code. You may not do anything else with the code
 * without express permission from Zilliqa Research Pte. Ltd., including
 * modifying or publishing the code (or any part of it), and developing or
 * forming another public or private blockchain network. This source code is
 * provided 'as is' and no warranties are given as to title or non-infringement,
 * merchantability or fitness for purpose and, to the extent permitted by law,
 * all liability for your use of the code is disclaimed. Some programs in this
 * code are governed by the GNU General Public License v3.0 (available at
 * https://www.gnu.org/licenses/gpl-3.0.en.html) ('GPLv3'). The programs that
 * are governed by GPLv3.0 are those programs that are located in the folders
 * src/depends and tests/depends and which include a reference to GPLv3 in their
 * program files.
 */

#ifndef __TIMESTAMPVERIFIER_H__
#define __TIMESTAMPVERIFIER_H__

#include "Logger.h"
#include "TimeUtils.h"
#include "common/Constants.h"

static bool VerifyTimestamp(const uint64_t& timestamp_in_microsec,
                            const uint64_t& timeout_in_sec) {
  uint64_t loBound, hiBound;

  loBound =
      get_time_as_int() >=
              (SYS_TIMESTAMP_VARIANCE_IN_SECONDS + timeout_in_sec) * 1000000
          ? get_time_as_int() -
                (SYS_TIMESTAMP_VARIANCE_IN_SECONDS + CONSENSUS_OBJECT_TIMEOUT) *
                    1000000
          : 0;

  if (!SafeMath<uint64_t>::add(get_time_as_int(),
                               (SYS_TIMESTAMP_VARIANCE_IN_SECONDS)*1000000,
                               hiBound)) {
    hiBound = std::numeric_limits<uint64_t>::max();
  }

  if (!is_timestamp_in_range(timestamp_in_microsec, loBound, hiBound)) {
    LOG_GENERAL(WARNING,
                "Timestamp check failed. Received: "
                    << timestamp_in_microsec << "("
                    << microsec_timestamp_to_readable(timestamp_in_microsec)
                    << ")"
                    << " Expected Range: " << loBound << "("
                    << microsec_timestamp_to_readable(loBound) << ")"
                    << " ~ " << hiBound << "("
                    << microsec_timestamp_to_readable(hiBound) << ")");
    return false;
  }

  return true;
}

#endif  // __TIMESTAMPVERIFIER_H__